<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
    <script>
    // 手写call
    // 原理：以 对象调用 的方法改变this指向
    Function.prototype.mycall = function(obj,...args){
      // console.log(this) // this指向要调用的函数
      // 1、非严格模式下，call传入undefined或null， 则this指向window
      if(obj === null || obj === undefined){
        obj = window
      }else{
        obj = Object(obj)
      }
      // obj = obj ?? window  可以使用空值合并操作符
      // obj.fun = this  // 1、给obj增加fun方法，指向要调用的函数（缺点：如果有同名会被覆盖，使用symbol）
      let fn = Symbol()
      obj[fn] = this // this为调用mycall的函数  fun
      return obj[fn](...args)   // 3、以 对象调用 的形式，this指向该对象，并返回结果
    }
    
    function fun(a,b){
      console.log(this)
      console.log(this.myname)
      console.log(a,b)
    }
    let obj = {
      myname:'aa'
    }
    // fun.call(obj)
    fun()
    fun.call(obj,1,2)
    fun.mycall(obj,1,2)
  </script>
</body>
</html>
